package search.restapi;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.stereotype.Component;

import search.config.AnalyzerNames;
import search.config.MediaTypes;
import common.helper.json.JsonToJavaObject;
import search.model.query.ComplexParameter;
import search.service.analysis.AnalysisService;
import search.service.debug.DebugAnalyzerService;
import search.service.search.ComplexSearchService_V2;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

/**
 * Created by julianzliu on 2016/7/1.
 */


@Path("/v1/debug")
@Produces(MediaTypes.JSON_UTF8)
@Component
public class DebugRestAPI {
    final Logger logger = LoggerFactory.getLogger(SearchRestAPI.class);

    private ObjectMapper mapper;

    private AnalysisService analysis_service;
    private DebugAnalyzerService debug_service;
    private ComplexSearchService_V2 complexSearchService;


    @Inject
    public DebugRestAPI(
            ObjectMapper mapper,
            DebugAnalyzerService debug_service,
            AnalysisService analysis_service,
            ComplexSearchService_V2 complexSearchService
    ) {
        this.mapper = mapper;
        this.debug_service = debug_service;
        this.analysis_service = analysis_service;
        this.complexSearchService = complexSearchService;
    }


    @PostConstruct
    private void init() {
       logger.info("Initialized /v1/debug/ Successfully !!!");
    }


    @GET
    @Path("/_search_with_analyzer")
    @Produces(MediaTypes.JSON_UTF8)
    public String search(
            @QueryParam("q") String q,
            @QueryParam("from") Integer from,
            @QueryParam("size") Integer size,
            @QueryParam("minimum") String minimum,
            @QueryParam("explain") String explain,
            @QueryParam("analyzer") String analyzer,
            @QueryParam("order") String order
    ) {
        Optional<String> oq = Optional.fromNullable(q);
        Optional<Integer> ofrom = Optional.fromNullable(from);
        Optional<Integer> osize = Optional.fromNullable(size);
        Optional<String> ominimum  = Optional.fromNullable(minimum);
        Optional<String> oexplain  = Optional.fromNullable(explain);
        Optional<String> oanalyzer = Optional.fromNullable(analyzer);
        Optional<String> oorder = Optional.fromNullable(order);
        return debug_service.debug_with_single_analyzer(
                oq.or(""),
                ofrom.or(0),
                osize.or(10),
                ominimum.or(""),
                oexplain.or("false"),
                oanalyzer.or(""),
                oorder.or("")
        );
    }



    @GET
    @Path("/_analyze")
    @Produces(MediaTypes.JSON_UTF8)
    public String analyze(
            @QueryParam("text") String text,
            @QueryParam("analyzer") String analyzer
    ){
        Optional<String> otext = Optional.fromNullable(text);
        Optional<String> oanalyzer= Optional.fromNullable(analyzer);
        return analysis_service.analyze(
                otext.or(""),
                oanalyzer.or(AnalyzerNames.default_index_analyzer)
        );
    }




    @GET
    @Path("/_explain")
    @Produces(MediaTypes.JSON_UTF8)
    public String explain(
            @QueryParam("q") String q,
            @QueryParam("id") String id
    ){
        Optional<String> oq = Optional.fromNullable(q);
        Optional<String> oid = Optional.fromNullable(id);
        return oq.or("Empty ") + oid.or("Empty");
    }



    @GET
    @Path("/_index_result")
    @Produces(MediaTypes.JSON_UTF8)
    public String index_result(
            @QueryParam("id") String id
    ){
        Optional<String> oid = Optional.fromNullable(id);
        return oid.or("Empty ID");
    }




    @GET
    @Path("/_dsl_generate")
    @Produces(MediaTypes.JSON_UTF8)
    public String complexDsl(
            @QueryParam("from")  @DefaultValue("0") Integer from,
            @QueryParam("size") @DefaultValue("10") Integer size,
            @QueryParam("fulltext") String fulltext,
            @QueryParam("pinyin") String pinyin,
            @QueryParam("level") String level,
            @QueryParam("levels") String levels,
            @QueryParam("minimum") String minimum,
            @QueryParam("mediatype") String mediatype,
            @QueryParam("sorttype") String sorttype,
            @QueryParam("source") String source,
            @QueryParam("mediaform") String mediaform,
            @QueryParam("subject") String subject,
            @QueryParam("region") String region,
            @QueryParam("mediasize") String mediasize,
            @QueryParam("format") String format,
            @QueryParam("copyright") String copyright,
            @QueryParam("shotdatefrom") String shotdatefrom,
            @QueryParam("shotdateto") String shotdateto,
            @QueryParam("explain") String explain
    ){
        Optional<String> new_dsl = Optional.fromNullable("true");
        return SearchRestAPI.complex_search(
                this.logger, this.mapper, this.complexSearchService,
                Optional.fromNullable(from), Optional.fromNullable(size), Optional.fromNullable(fulltext), Optional.fromNullable(pinyin),
                Optional.fromNullable(level), Optional.fromNullable(minimum), Optional.fromNullable(mediatype), Optional.fromNullable(sorttype),
                Optional.fromNullable(source), Optional.fromNullable(mediaform),
                Optional.fromNullable(subject), Optional.fromNullable(region), Optional.fromNullable(mediasize),
                Optional.fromNullable(format), Optional.fromNullable(copyright), Optional.fromNullable(shotdatefrom), Optional.fromNullable(shotdateto),
                Optional.fromNullable(explain),  new_dsl
        );
    }

    @POST
    @Path("/_dsl_generate")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaTypes.JSON_UTF8)
    public String complexDslPost(ComplexParameter adpara){
        adpara.setDsl("true");
        return complexSearchService.complexSearch(adpara);
    }




    @POST
    @Path("/_dsl_query")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaTypes.JSON_UTF8)
    public String queryDsl(String  dsl_json)
    {
        JsonNode dsl = JsonToJavaObject.loadJsonNode(dsl_json);
        String match_all_sal =
                "{\n" +
                "   \"query\": {\n" +
                "       \"match_all\": {}\n" +
                "   }\n" +
                "}\n";
        if(dsl.size() == 0) return match_all_sal;
        return dsl.toString();
    }



}
